package com.ikingtech.platform.service.system.dept.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.approve.api.ApproveFormDepartmentApi;
import com.ikingtech.framework.sdk.approve.model.ApproveFormDepartment;
import com.ikingtech.framework.sdk.approve.model.ApproveFormDepartmentManager;
import com.ikingtech.framework.sdk.department.api.DeptUserApi;
import com.ikingtech.framework.sdk.department.model.DeptManagerDTO;
import com.ikingtech.framework.sdk.enums.system.department.DeptTypeEnum;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.system.dept.entity.DepartmentDO;
import com.ikingtech.platform.service.system.dept.service.repository.DeptRepository;
import lombok.RequiredArgsConstructor;

import java.util.*;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public class ApproveFormDepartmentService implements ApproveFormDepartmentApi {

    private final DeptRepository repo;

    private final DeptUserApi deptUserApi;

    @Override
    public ApproveFormDepartment loadById(String deptId) {
        DepartmentDO entity = this.repo.getById(deptId);
        if (null != entity) {
            ApproveFormDepartment formDept = new ApproveFormDepartment();
            formDept.setDeptId(entity.getId());
            formDept.setDeptName(entity.getName());
            formDept.setDeptType(DeptTypeEnum.valueOf(entity.getType()));
            formDept.setDeptFullPath(entity.getFullPath());
            return formDept;
        }
        return null;
    }

    @Override
    public Map<String, ApproveFormDepartment> mapByIds(List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return new HashMap<>();
        }
        List<DepartmentDO> entities = this.repo.list(Wrappers.<DepartmentDO>lambdaQuery().in(DepartmentDO::getId, deptIds));
        List<DeptManagerDTO> managers = this.deptUserApi.loadManagers(Tools.Coll.convertList(entities, DepartmentDO::getManagerId));
        Map<String, DeptManagerDTO> managerMap = Tools.Coll.convertMap(managers, DeptManagerDTO::getUserId);
        return Tools.Coll.convertMap(entities, DepartmentDO::getId, entity -> {
            ApproveFormDepartment formDept = new ApproveFormDepartment();
            formDept.setDeptId(entity.getId());
            formDept.setDeptName(entity.getName());
            if (managerMap.containsKey(entity.getManagerId())) {
                formDept.setDeptManagerId(entity.getManagerId());
                formDept.setDeptManagerName(managerMap.get(entity.getManagerId()).getUserName());
                formDept.setDeptManagerAvatar(managerMap.get(entity.getManagerId()).getUserAvatar());
            }
            return formDept;
        });
    }

    @Override
    public String findUnitId(String deptId) {
        return this.repo.findUnityId(deptId);
    }

    @Override
    public List<String> findUnitIds(List<String> deptIds) {
        return this.repo.findUnityIds(deptIds);
    }

    @Override
    public ApproveFormDepartmentManager loadManager(String deptId) {
        String managerUserId = this.repo.getObj(Wrappers.<DepartmentDO>lambdaQuery().eq(DepartmentDO::getManagerId, deptId), String.class::cast);
        return Tools.Str.isBlank(managerUserId) ? null : Tools.Bean.copy(this.deptUserApi.loadManager(managerUserId), ApproveFormDepartmentManager.class);
    }

    @Override
    public String loadIdByParentLevel(String deptId, int level) {
        String fullPath = this.repo.getObj(Wrappers.<DepartmentDO>lambdaQuery().select(DepartmentDO::getFullPath).eq(DepartmentDO::getId, deptId), String.class::cast);
        if (Tools.Str.isBlank(fullPath)) {
            return Tools.Str.EMPTY;
        }
        List<String> parentDeptIdsByFullPath = Tools.Str.split(fullPath);
        if (parentDeptIdsByFullPath.size() < level + 1) {
            return Tools.Str.EMPTY;
        }
        return parentDeptIdsByFullPath.get(parentDeptIdsByFullPath.size() - (level + 1));
    }

    @Override
    public List<String> loadIdByName(String deptName, String tenantCode) {
        return this.repo.listObjs(Wrappers.<DepartmentDO>lambdaQuery().select(DepartmentDO::getId)
                .eq(DepartmentDO::getTenantCode, tenantCode)
                .like(DepartmentDO::getName, deptName));
    }
}
